package com.ruoyi.security.dto.backtest;

import com.ruoyi.security.enums.OverstepPriceRangeActionEnum;
import lombok.Data;

import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;

/**
 * @author yeoman
 * @date 2025/2/4 21:56
 * @description 网格交易回测参数
 */
@Data
public class SecurityGridTradingBacktestParamDto {

    /**
     * 标的代码
     */
    @NotBlank(message = "代码不能为空")
    private String symbol;

    /**
     * 回测周期
     */
    @Valid
    @NotNull(message = "回测周期不能为空")
    private BacktestPeriod backtestPeriod;

    /**
     * 触发条件
     */
    @Valid
    @NotNull(message = "触发条件不能为空")
    private TriggerCondition triggerCondition;

    /**
     * 委托设置
     */
    @Valid
    @NotNull(message = "委托设置不能为空")
    private MandateSettings mandateSettings;

    /**
     * 高级设置
     */
    private AdvancedSetting advancedSetting;

    /**
     * 交易手续费
     */
    @Valid
    @NotNull(message = "交易手续费不能为空")
    private TradeCharge tradeCharge;

    @Data
    public static class BacktestPeriod {
        /**
         * 回测开始日期
         */
        @NotBlank(message = "回测开始日期不能为空")
        private String startDate;
        /**
         * 回测结束日期
         */
        @NotBlank(message = "回测结束日期不能为空")
        private String endDate;
    }

    @Data
    public static class TriggerCondition{
        /**
         * 涨跌类型
         * @see com.ruoyi.security.enums.RiseFallTypeEnum
         */
        @NotBlank(message = "涨跌类型不能为空")
        private String riseFallType;

        /**
         * 初始基准价
         */
        @NotNull(message = "初始基准价不能为空")
        private BigDecimal initialBenchmarkPrice;

        /**
         * 股价每上涨（按价格差：分；按百分比：%）卖出
         */
        @NotNull(message = "股价每上涨不能为空")
        private BigDecimal perRiseValue;

        /**
         * 股价每下跌（按价格差：分；按百分比：%）买入
         */
        @NotNull(message = "股价每下跌不能为空")
        private BigDecimal perFallValue;
    }

    @Data
    public static class MandateSettings{

        /**
         * 初始持仓
         */
        @NotNull(message = "初始持仓不能为空")
        private Integer initialPosition;

        /**
         * 初始可用资金
         */
        private BigDecimal initialAvailableAmount;

        /**
         * 委托数量
         */
        @Valid
        @NotNull(message = "委托数量不能为空")
        private MandateQuantity mandateQuantity;

        /**
         * 基准价更新方式
         * @see com.ruoyi.security.enums.BenchmarkPriceUpdateTypeEnum
         */
        @NotBlank(message = "基准价更新方式不能为空")
        private String benchmarkPriceUpdateType;

        @Data
        public static class MandateQuantity {
            /**
             * 单笔买入数量
             */
            @NotNull(message = "单笔买入数量不能为空")
            private Integer singleBuyQuantity;

            /**
             * 单笔卖出数量
             */
            @NotNull(message = "单笔卖出数量不能为空")
            private Integer singleSellQuantity;
        }

        /**
         * 委托金额
         */
        private MandateAmount mandateAmount;

        @Data
        public static class MandateAmount {
            /**
             * 每笔买入金额（元）
             */
            private BigDecimal buyAmount;
            /**
             * 每笔卖出金额（元）
             */
            private BigDecimal sellAmount;
        }

    }

    @Data
    public static class AdvancedSetting {

        /**
         * 价格区间
         */
        private PriceRange priceRange;

        /**
         * 持仓范围
         */
        private PositionRange positionRange;

        /**
         * 倍数委托开关
         */
        private Boolean multipleMandateSwitch;

        @Data
        public static class PriceRange {

            /**
             * 价格下限（选填）
             */
            private BigDecimal priceFloor;

            /**
             * 价格上限（选填）
             */
            private BigDecimal priceCeiling;

            /**
             * 超出下限动作，默认：休眠
             */
            private OverstepPriceRangeActionEnum overstepFloorAction = OverstepPriceRangeActionEnum.SLEEP_STATE;

            /**
             * 超出上限动作，默认：休眠
             */
            private OverstepPriceRangeActionEnum overstepCeilingAction = OverstepPriceRangeActionEnum.SLEEP_STATE;
        }

        @Data
        public static class PositionRange {

            /**
             * 持仓下限（选填）
             */
            private Integer positionFloor;

            /**
             * 持仓上限（选填）
             */
            private Integer positionCeiling;

        }

    }

    @Data
    public static class TradeCharge {
        /**
         * 券商佣金万分之（默认万2.5元）
         */
        @NotNull(message = "券商佣金万分之不能为空")
        private BigDecimal commissionTenThousandth;

        /**
         * 是否免最低佣金（默认否）
         */
        @NotNull(message = "是否免最低佣金不能为空")
        private Boolean freeMinimumCommission;

    }

}
